#include "widget.h"
#include "ui_Ui_Widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Ui_Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("RGBA叠加色计算器");
    this->connectSingls();
}

Widget::~Widget()
{
    delete ui;
}

void Widget::connectSingls()
{
    //切换页面
    connect(ui->forward,&QPushButton::clicked,ui->stackedWidget,std::bind(&QStackedWidget::setCurrentIndex,ui->stackedWidget,0));
    connect(ui->reverse,&QPushButton::clicked,ui->stackedWidget,std::bind(&QStackedWidget::setCurrentIndex,ui->stackedWidget,1));
    //正向全部清空
    for(auto& v : this->ui->stackedWidget->widget(0)->findChildren<QSpinBox*>())
        connect(ui->forward_all_clear,&QPushButton::clicked,v, std::bind(&QSpinBox::setValue,v,0));
    for(auto& v : this->ui->stackedWidget->widget(0)->findChildren<QLineEdit*>())
        connect(ui->forward_all_clear,&QPushButton::clicked,v,&QLineEdit::clear);
    for(auto& v : this->ui->stackedWidget->widget(0)->findChildren<ColorLabel*>())
        connect(ui->forward_all_clear,&QPushButton::clicked,v,std::bind(&ColorLabel::setBackgroundkColor,v,QColor(0,0,0,0)));
    //正向颜色1清空
    for(auto& v : this->ui->widget->findChildren<QSpinBox*>())
        connect(ui->forward_initial_1_clear,&QPushButton::clicked,v,std::bind(&QSpinBox::setValue,v,0));
    for(auto& v : this->ui->widget->findChildren<QLineEdit*>())
        connect(ui->forward_initial_1_clear,&QPushButton::clicked,v,&QLineEdit::clear);
    for(auto& v : this->ui->widget->findChildren<ColorLabel*>())
        connect(ui->forward_initial_1_clear,&QPushButton::clicked,v,std::bind(&ColorLabel::setBackgroundkColor,v,QColor(0,0,0,0)));
    //正向颜色2清空
    for(auto& v : this->ui->widget_3->findChildren<QSpinBox*>())
        connect(ui->forward_initial_2_clear,&QPushButton::clicked,v,std::bind(&QSpinBox::setValue,v,0));
    for(auto& v : this->ui->widget_3->findChildren<QLineEdit*>())
        connect(ui->forward_initial_2_clear,&QPushButton::clicked,v,&QLineEdit::clear);
    for(auto& v : this->ui->widget_3->findChildren<ColorLabel*>())
        connect(ui->forward_initial_2_clear,&QPushButton::clicked,v,std::bind(&ColorLabel::setBackgroundkColor,v,QColor(0,0,0,0)));
    //正向计算叠加计算
    for(auto& v : this->ui->stackedWidget->widget(0)->findChildren<QSpinBox*>())
        connect(v,&QSpinBox::valueChanged,this,[this](){
            QColor color1;
            color1.setAlpha(this->ui->forward_initial_1_A->value());
            color1.setRed(this->ui->forward_initial_1_R->value());
            color1.setGreen(this->ui->forward_initial_1_G->value());
            color1.setBlue(this->ui->forward_initial_1_B->value());

            QColor color2;
            color2.setAlpha(this->ui->forward_initial_2_A->value());
            color2.setRed(this->ui->forward_initial_2_R->value());
            color2.setGreen(this->ui->forward_initial_2_G->value());
            color2.setBlue(this->ui->forward_initial_2_B->value());

            QColor result1 = this->superpositionColorComputation(color1,color2);
            QColor result2 = this->superpositionColorComputation(color2,color1);

            this->ui->forward_initial_1_label->setBackgroundkColor(color1);
            this->ui->forward_initial_2_label->setBackgroundkColor(color2);
            this->ui->forward_result_1_label->setBackgroundkColor(result1);
            this->ui->forward_result_2_label->setBackgroundkColor(result2);

            this->ui->forward_result_1_A->setText(QString::number(result1.alpha()));
            this->ui->forward_result_1_R->setText(QString::number(result1.red()));
            this->ui->forward_result_1_G->setText(QString::number(result1.green()));
            this->ui->forward_result_1_B->setText(QString::number(result1.blue()));
            this->ui->forward_result_1_RGBA->setText("rgba("+QString::number(result1.red())+","+QString::number(result1.green())+","+QString::number(result1.blue())+","+QString::number(result1.alpha())+")");

            this->ui->forward_result_2_A->setText(QString::number(result2.alpha()));
            this->ui->forward_result_2_R->setText(QString::number(result2.red()));
            this->ui->forward_result_2_G->setText(QString::number(result2.green()));
            this->ui->forward_result_2_B->setText(QString::number(result2.blue()));
            this->ui->forward_result_2_RGBA->setText("rgba("+QString::number(result2.red())+","+ QString::number(result2.green())+","+QString::number(result2.blue())+","+QString::number(result2.alpha())+")");
        });
    //正向计算结果复制
    connect(ui->forward_result_1_copy, &QPushButton::clicked,this, [this]() {
        if(ui->forward_result_1_RGBA->text().isEmpty() || ui->forward_result_1_RGBA->text().isNull())
            return;
        QClipboard *clipboard = QApplication::clipboard();// 获取剪贴板对象
        clipboard->setText(ui->forward_result_1_RGBA->text(), QClipboard::Clipboard);// 将文本框内容复制到剪贴板
    });
    connect(ui->forward_result_2_copy, &QPushButton::clicked,this, [this]() {
        if(ui->forward_result_2_RGBA->text().isEmpty() || ui->forward_result_2_RGBA->text().isNull())
            return;
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(ui->forward_result_2_RGBA->text(), QClipboard::Clipboard);
    });

    //逆向,全部清空
    for(auto& v : this->ui->stackedWidget->widget(1)->findChildren<QSpinBox*>())
        connect(ui->reverse_all_clear,&QPushButton::clicked,v,std::bind(&QSpinBox::setValue,v,0));
    for(auto& v : this->ui->stackedWidget->widget(1)->findChildren<QLineEdit*>())
        connect(ui->reverse_all_clear,&QPushButton::clicked,v,&QLineEdit::clear);
    //逆向,覆盖后颜色清空
    for(auto& v : this->ui->widget_7->findChildren<QSpinBox*>())
        connect(ui->reverse_initial_1_clear,&QPushButton::clicked,v,std::bind(&QSpinBox::setValue,v,0));
    for(auto& v : this->ui->widget_7->findChildren<QLineEdit*>())
        connect(ui->reverse_initial_1_clear,&QPushButton::clicked,v,&QLineEdit::clear);
    //逆向,覆盖颜色之一清空
    for(auto& v : this->ui->widget_8->findChildren<QSpinBox*>())
        connect(ui->reverse_initial_2_clear,&QPushButton::clicked,v,std::bind(&QSpinBox::setValue,v,0));
    for(auto& v : this->ui->widget_8->findChildren<QLineEdit*>())
        connect(ui->reverse_initial_2_clear,&QPushButton::clicked,v,&QLineEdit::clear);
    //逆向计算
    auto func = [this](bool isCalculate = true){
        if(!isCalculate)
            return;
        if(this->ui->reverse_initial_1_A->value() == 0 || this->ui->reverse_initial_1_A->value() < this->ui->reverse_initial_2_A->value())
        {
            this->ui->reverse_result_label->setBackgroundkColor(QColor(0,0,0,0));
            this->ui->reverse_result_A->clear();
            this->ui->reverse_result_R->clear();
            this->ui->reverse_result_G->clear();
            this->ui->reverse_result_B->clear();
            this->ui->reverse_result_RGBA->clear();
            return;
        }

        QColor final;
        final.setAlpha(this->ui->reverse_initial_1_A->value());
        final.setRed(this->ui->reverse_initial_1_R->value());
        final.setGreen(this->ui->reverse_initial_1_G->value());
        final.setBlue(this->ui->reverse_initial_1_B->value());

        QColor oneOf;
        oneOf.setAlpha(this->ui->reverse_initial_2_A->value());
        oneOf.setRed(this->ui->reverse_initial_2_R->value());
        oneOf.setGreen(this->ui->reverse_initial_2_G->value());
        oneOf.setBlue(this->ui->reverse_initial_2_B->value());


        this->ui->reverse_initial_1_label->setBackgroundkColor(final);
        this->ui->reverse_initial_2_label->setBackgroundkColor(oneOf);

        float A  = (final.alphaF()-oneOf.alphaF())/(1-oneOf.alphaF());
        float R ;
        float G ;
        float B ;

        bool is_one_of_upper = ui->reverse_initial_2_upper->isChecked();
        if(is_one_of_upper)
        {
            R = ((final.redF()*final.alphaF())-(oneOf.redF()*oneOf.alphaF()))/(A*(1-oneOf.alphaF()));
            G = ((final.greenF()*final.alphaF())-(oneOf.greenF()*oneOf.alphaF()))/(A*(1-oneOf.alphaF()));
            B = ((final.blueF()*final.alphaF())-(oneOf.blueF()*oneOf.alphaF()))/(A*(1-oneOf.alphaF()));
        }
        else
        {
            R = ((final.redF()*final.alphaF()) - ((oneOf.redF()*oneOf.alphaF())*(1-A)))/A;
            G = ((final.greenF()*final.alphaF()) - ((oneOf.greenF()*oneOf.alphaF())*(1-A)))/A;
            B = ((final.blueF()*final.alphaF()) - ((oneOf.blueF()*oneOf.alphaF())*(1-A)))/A;
        }

        if(R < 0 || G < 0 || B < 0 || R > 1 || G > 1 || B >1)
        {
            this->ui->reverse_result_label->setBackgroundkColor(QColor(0,0,0,0));
            this->ui->reverse_result_A->clear();
            this->ui->reverse_result_R->clear();
            this->ui->reverse_result_G->clear();
            this->ui->reverse_result_B->clear();
            this->ui->reverse_result_RGBA->clear();
            return;
        }
        QColor result = QColor::fromRgbF(R, G, B, A);//计算结果
        this->ui->reverse_result_label->setBackgroundkColor(result);

        this->ui->reverse_result_A->setText(QString::number(result.alpha()));
        this->ui->reverse_result_R->setText(QString::number(result.red()));
        this->ui->reverse_result_G->setText(QString::number(result.green()));
        this->ui->reverse_result_B->setText(QString::number(result.blue()));
        this->ui->reverse_result_RGBA->setText("rgba("+QString::number(result.red())+","+QString::number(result.green())+","+QString::number(result.blue())+","+QString::number(result.alpha())+")");
    };
    for(auto& v : this->ui->stackedWidget->widget(1)->findChildren<QSpinBox*>())
        connect(v,&QSpinBox::valueChanged,this,func);
    connect(ui->reverse_initial_2_under,&QRadioButton::toggled,this,func);
    connect(ui->reverse_initial_2_upper,&QRadioButton::toggled,this,func);
    //逆向计算结果复制
    connect(ui->reverse_result_copy, &QPushButton::clicked,this, [this]() {
        if(ui->reverse_result_RGBA->text().isEmpty() || ui->reverse_result_RGBA->text().isNull())
            return;
        QClipboard *clipboard = QApplication::clipboard();
        clipboard->setText(ui->reverse_result_RGBA->text(), QClipboard::Clipboard);
    });
}

QColor Widget::superpositionColorComputation(const QColor& upper, const QColor& under)
{
    float Aa = upper.alphaF();
    float Ar = upper.redF();
    float Ag = upper.greenF();
    float Ab = upper.blueF();

    float Ba = under.alphaF();
    float Br = under.redF();
    float Bg = under.greenF();
    float Bb = under.blueF();

    float A = Aa + Ba * (1 - Aa);
    float R = (Ar * Aa + Br * Ba * (1 - Aa)) / A;
    float G = (Ag * Aa + Bg * Ba * (1 - Aa)) / A;
    float B = (Ab * Aa + Bb * Ba * (1 - Aa)) / A;

    return QColor::fromRgbF(R, G, B, A);
}


void ColorLabel::setBackgroundkColor(const QColor &color)
{
    this->bk = color;
    update();
}

void ColorLabel::paintEvent(QPaintEvent *event)
{
    QLabel::paintEvent(event);
    QPainter painter(this);
    painter.setPen(Qt::NoPen);
    painter.setBrush(this->bk);
    painter.drawRect(this->rect());
}
